

package net.qiqbframework.modelling.repository;


import net.qiqbframework.common.BuilderUtils;
import net.qiqbframework.tracing.Span;
import net.qiqbframework.tracing.SpanFactory;

public class DefaultRepositorySpanFactory implements RepositorySpanFactory {

    private final SpanFactory spanFactory;
    private final String aggregateIdAttribute;


    protected DefaultRepositorySpanFactory(Builder builder) {
        builder.validate();
        this.spanFactory = builder.builderSpanFactory;
        this.aggregateIdAttribute = builder.builderAggregateIdAttribute;
    }

    public static Builder builder() {
        return new Builder();
    }

    @Override
    public Span createLoadSpan(String aggregateId) {
        return spanFactory.createInternalSpan(() -> "Repository.load")
                .addAttribute(aggregateIdAttribute, aggregateId);
    }

    @Override
    public Span createObtainLockSpan(String aggregateId) {
        return spanFactory.createInternalSpan(() -> "Repository.obtainLock")
                .addAttribute(aggregateIdAttribute, aggregateId);
    }

    @Override
    public Span createInitializeStateSpan(String aggregateType, String aggregateId) {
        return spanFactory.createInternalSpan(() -> "Repository.initializeState(" + aggregateType + ")")
                .addAttribute(aggregateIdAttribute, aggregateId);
    }

    public static class Builder {

        private SpanFactory builderSpanFactory;
        private String builderAggregateIdAttribute = "qiqb.aggregateId";


        public Builder spanFactory(SpanFactory spanFactory) {
            BuilderUtils.assertNonNull(spanFactory, "spanFactory may not be null");
            this.builderSpanFactory = spanFactory;
            return this;
        }

        public Builder aggregateIdAttribute(String aggregateIdAttribute) {
            BuilderUtils.assertNonEmpty(aggregateIdAttribute, "aggregateIdAttribute may not be null");
            this.builderAggregateIdAttribute = aggregateIdAttribute;
            return this;
        }

        protected void validate() {
            BuilderUtils.assertNonNull(builderSpanFactory, "spanFactory may not be null");
        }

        public DefaultRepositorySpanFactory build() {
            return new DefaultRepositorySpanFactory(this);
        }
    }
}
